//
//  DMRLog.swift
//  XiaoweHealthy
//
//  Created by Riven on 2022/4/9.
//

import Foundation
import SwiftyBeaver

@objc public class DMRLog: NSObject {
    
    private static var logDirName: String = "AppLogDir"
    private static var logFileName: String = "AppLog.log"
    
    private static var logClass: SwiftyBeaver.Type = SwiftyBeaver.self
    
    @objc public class func configLog(_ logDirName: String?, logFileName: String?) {
        if let logDirName = logDirName, logDirName.isEmpty {
            self.logDirName = logDirName
        }
        if let logFileName = logFileName, logFileName.isEmpty {
            self.logFileName = logFileName
        }
        
        let logFormat = "$Dyyyy-MM-dd HH:mm:ss.SSS$d $C$L$c $N.$F:$l - $M"
        
        let console = ConsoleDestination()
        console.format = logFormat
        
        var logUrl: URL?
        if let logDirUrl = getLogDir() {
            logUrl = logDirUrl.appendingPathComponent(self.logFileName, isDirectory: false)
        }
        let file = FileDestination(logFileURL: logUrl)
        file.format = logFormat
        file.logFileAmount = 4
        
        #if DEBUG
        file.minLevel = .debug
        #else
        file.minLevel = .info
        #endif
        
        logClass.addDestination(console)
        logClass.addDestination(file)
        
        logClass.info("----------------日志开始----------------")
        logClass.info("logFileURL = \(file.logFileURL?.absoluteString ?? "")")
    }
    
    @objc public class func getLogDir() -> URL? {
        let logDirUrl = createLogDir()
        
        return logDirUrl
    }

    private class func createLogDir() -> URL? {
        do {
            guard let logBaseUrl = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else {
                return nil
            }
            let logDirUrl = logBaseUrl.appendingPathComponent(logDirName)
            var isDirectory: ObjCBool = true
            let logDirPath = logDirUrl.path
            if !FileManager.default.fileExists(atPath: logDirPath, isDirectory: &isDirectory) {
                try FileManager.default.createDirectory(at: logDirUrl, withIntermediateDirectories: true)
            }
            
            return logDirUrl
        } catch let error {
            logClass.error(error)
            return nil
        }
    }
    
    // MARK: - log swift
    open class func logVerbose(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) {
//        logClass.verbose(message, filePath, self.convertFunction(function), line: line, context: nil)
        logClass.verbose(message(), file: file, function: function, line: line)
    }
    
    class func logDebug(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) {
        logClass.debug(message(), file: file, function: function, line: line)
    }
    
    open class func logInfo(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) {
        logClass.info(message(), file: file, function: function, line: line)
        
    }
    
    open class func logWarning(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) {
        logClass.warning(message(), file: file, function: function, line: line)
    }
    
    open class func logError(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) {
        logClass.error(message(), file: file, function: function, line: line)
    }
    
    // MARK: - log OC
    @objc open class func logOCVerbose(_ message: String, file: String, function: String, line: Int) {
        logVerbose(message, file: file, function: convertFunction(function), line: line)
    }

    @objc open class func logOCDebug(_ message: String, file: String, function: String, line: Int) {
        logDebug(message, file: file, function: convertFunction(function), line: line)
    }

    @objc open class func logOCInfo(_ message: String, file: String, function: String, line: Int) {
        logInfo(message, file: file, function: convertFunction(function), line: line)
    }

    @objc open class func logOCWarning(_ message: String, file: String, function: String, line: Int) {
        logWarning(message, file: file, function: convertFunction(function), line: line)
    }

    @objc open class func logOCError(_ message: String, file: String, function: String, line: Int) {
        logError(message, file: file, function: convertFunction(function), line: line)
    }

    
    // For OC
    @objc private class func convertFunction(_ function: String) -> String {
        var strippedFunction = function
        
        if let match = function.range(of: "\\w+:*[\\w*:*]*]", options: .regularExpression) {
            let endIndex = function.index(before: match.upperBound)
            let functionParts = function[match.lowerBound..<endIndex].components(separatedBy: ":")

            guard functionParts.count > 0 else { return function }
            
            for (index, part) in functionParts.enumerated() {
                switch index {
                case 0:
                    strippedFunction = part
                    if functionParts.count > 1 { strippedFunction += "(_:" }
                default:
                    if !part.isEmpty {
                        strippedFunction += "\(part):"
                    }
                }
            }
            if functionParts.count > 1 { strippedFunction += ")" }
            else if functionParts.count == 1 { strippedFunction += "()" }
            
        }
        return strippedFunction
    }

    private override init() {
        
    }
    
}
